#include "database_manager.h"
#include <spdlog/spdlog.h>

DatabaseManager::DatabaseManager(const std::string& db_path) : db_(db_path) {
    spdlog::info("DatabaseManager constructor called with path: {}", db_path);
    if (!db_.is_valid()) {
        spdlog::error("Failed to open database: {}", db_.get_error_message());
    } else {
        spdlog::info("Database connection opened successfully");
    }
}

DatabaseConnection& DatabaseManager::getDatabaseConnection() {
    spdlog::info("getDatabaseConnection called");
    return db_;
}

void DatabaseManager::initialize() {
    spdlog::info("DatabaseManager::initialize() called");
    
    if (!db_.is_valid()) {
        spdlog::error("Database connection is not valid");
        return;
    }
    
    // Create users table
    spdlog::info("Creating users table...");
    PreparedStatement create_users_table(db_, 
        "CREATE TABLE IF NOT EXISTS users ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "username TEXT UNIQUE NOT NULL,"
        "password TEXT NOT NULL,"
        "created_at TEXT NOT NULL,"
        "updated_at TEXT NOT NULL"
        ")");
    
    // Check if statement was prepared successfully
    // Note: has_row() is not the right check here, we need to check if stmt_ is valid
    // Let's check if there was an error in preparing the statement by trying to step it
    DbError error = create_users_table.step();
    if (error != DbError::SUCCESS) {
        spdlog::error("Failed to create users table. Error: {}", static_cast<int>(error));
        return;
    }
    spdlog::info("Users table created successfully");

    // Create sessions table
    spdlog::info("Creating sessions table...");
    PreparedStatement create_sessions_table(db_,
        "CREATE TABLE IF NOT EXISTS sessions ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "user_id INTEGER NOT NULL,"
        "token TEXT UNIQUE NOT NULL,"
        "created_at TEXT NOT NULL,"
        "expires_at TEXT NOT NULL,"
        "FOREIGN KEY (user_id) REFERENCES users (id)"
        ")");
    
    error = create_sessions_table.step();
    if (error != DbError::SUCCESS) {
        spdlog::error("Failed to create sessions table. Error: {}", static_cast<int>(error));
        return;
    }
    spdlog::info("Sessions table created successfully");

    // Check if we need to create the default admin user
    spdlog::info("Checking user count...");
    PreparedStatement count_users(db_, "SELECT COUNT(*) FROM users");
    error = count_users.step();
    if (error == DbError::SUCCESS) {
        // For SELECT COUNT(*), we expect one row
        int user_count = count_users.column_int(0);
        spdlog::info("User count: {}", user_count);
        if (user_count == 0) {
            // Create default admin user
            spdlog::info("Creating default admin user...");
            std::string hashedPassword = hash_password("admin123");
            PreparedStatement insert_admin(db_, 
                "INSERT INTO users (username, password, created_at, updated_at) VALUES (?, ?, ?, ?)");
            
            DbError bind_error = insert_admin.bind_text(1, "admin");
            if (bind_error != DbError::SUCCESS) {
                spdlog::error("Failed to bind admin username: {}", static_cast<int>(bind_error));
                return;
            }
            
            bind_error = insert_admin.bind_text(2, hashedPassword);
            if (bind_error != DbError::SUCCESS) {
                spdlog::error("Failed to bind admin password: {}", static_cast<int>(bind_error));
                return;
            }
            
            bind_error = insert_admin.bind_text(3, "2023-01-01 00:00:00");
            if (bind_error != DbError::SUCCESS) {
                spdlog::error("Failed to bind admin created_at: {}", static_cast<int>(bind_error));
                return;
            }
            
            bind_error = insert_admin.bind_text(4, "2023-01-01 00:00:00");
            if (bind_error != DbError::SUCCESS) {
                spdlog::error("Failed to bind admin updated_at: {}", static_cast<int>(bind_error));
                return;
            }
            
            DbError insert_error = insert_admin.step();
            if (insert_error != DbError::SUCCESS) {
                spdlog::error("Failed to create default admin user: {}", static_cast<int>(insert_error));
                return;
            }
            spdlog::info("Default admin user created successfully");
        }
    } else {
        spdlog::error("Failed to execute count_users statement: {}", static_cast<int>(error));
        return;
    }
    
    spdlog::info("DatabaseManager::initialize() completed");
}